/*
 * Copyright (C) 2025 Tsingteng MicroSystem
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "nfa_base.h"
#include "nfa_wiredse_api.h"

typedef enum {
    WIREDSE_STATE_INIT = 0, // 未初始化状态
    WIREDSE_STATE_IDLE, // 空闲状态，可以接收指令
    WIREDSE_STATE_OPENNING,
    WIREDSE_STATE_OPENED,
    WIREDSE_STATE_WAIT_RAPDU,
} tWIREDSE_STATE;

typedef union {
    tAPDU apdu;
    tAPDU atr;
} tWIREDSE_MESSAGE_CONTENT;

typedef enum {
    WIREDSE_EVT_UNKNOWN = 0,
    WIREDSE_EVT_ABORT,
    WIREDSE_EVT_END_APDU,
    WIREDSE_EVT_SEND_APDU,
    WIREDSE_EVT_RECV_APDU,
    WIREDSE_EVT_RECV_ATR,
    WIREDSE_EVT_RECV_WTX,
    WIREDSE_EVT_TIMEOUT,
} tWIREDSE_EVENT;

typedef struct {
    tWIREDSE_EVENT event;
    tWIREDSE_MESSAGE_CONTENT content;
} tWIREDSE_RESULT;

typedef struct {
    uint32_t max_rapdu_wait_time;
} tWIREDSE_PROP;

/**
 * @brief wiredse状态机
 * @note 事件开始处理时会持有g_wiredse_lock锁
 *       如果是指令请求类型(abort、end apdu、发送apdu)，并且请求被状态机正确处理了，
 *       g_wiredse_lock锁不会被释放，请求方继续使用这个锁等待执行结果。
 *
 *       指令被拒绝/不处理，处理发生错误，还有其他请求被处理完成后g_wiredse_lock都会被释放
 *
 *       操作返回NCI_STATUS_OK时，content内容由本方法进行回收或者传给对应的回调方法
 *       返回其他值时，请求方需要把content的内存进行回收
 *       例外：WIREDSE_EVT_SEND_APDU的内容可能来自常量或者栈内存，故不做回收处理，由调用方回收
 *
 *       开始处理事件时会检查是否有事件处理结果未被处理
 *       如果有未处理的事件会直接把对应资源进行回收
 *
 *       事件被处理完成时，如果有结果需要返回，会存放在g_wiredse_result中，
 *       处理结果前需要等待到对应的事件并持有g_wiredse_lock，处理完成并销毁结果的内存后再释放锁
 * @param event 发生的事件
 * @param content event内容
 * @return 事件被成功处理返回NCI_STATUS_OK
 *         事件被拒绝/不处理返回NCI_STATUS_EXT_REJECTED
 */
tNCI_STATUS wiredse_sm(tWIREDSE_EVENT event, tWIREDSE_MESSAGE_CONTENT *content);

/**
 * @brief 释放g_wiredse_result中的内存
 * @note 此方法需要再g_wiredse_lock临界区中使用
 */
void wiredse_clean_result(void);
